import lodash from "lodash";

export class AppStore<IAppState={}> {
    private state: any = {};
    private reduers: AppViewStore.IRegisteReducer = {};
    private listener: Record<string, ({ id: string, callback: Function })[]> = {};
    /**
     * 注册state数据格式处理方法
     * @param name 注册节点
     * @param reducer 数据处理方法
     */
    public registeState(name: string, reducerHandler: Function, initStateData?: any) {
        if(!this.reduers[name]) {
            const tempState = {};
            lodash.set(tempState, name, initStateData);
            lodash.merge(this.state, tempState);
            this.reduers[name] = {
                initState: initStateData,
                handler: reducerHandler
            };
        } else {
            console.error(`要注册的reducer已经存在了, name: ${name}`);
        }
    }
    public initState(): void {
        Object.keys(this.reduers).forEach((key) => {
            const tempState = {};
            const { handler, initState: initStateData } = this.reduers[key];
            const initState = handler(initStateData, {
                state: this.state,
                action: {
                    type: "@Store_Init",
                    data: initStateData,
                    name: key
                }
            });
            const eventHandler = this.listener[key];
            lodash.set(tempState, key, initState);
            lodash.merge(this.state, tempState);
            if(eventHandler) {
                eventHandler.forEach((item) => {
                    item.callback(initState, this.state);
                });
            }
        });
    }
    /**
     * 销毁节点
     * @param name 节点名称
     */
    public unRegisteState(name: string): void {
        if(this.reduers[name]) {
            const { handler } = this.reduers[name];
            handler(lodash.get(this.state, name), {
                state: this.state,
                action: {
                    type: "@Store_Destroy",
                    name
                }
            })
            delete this.reduers[name];
        }
    }
    public destory() {
        this.reduers = {};
        this.state = {};
    }
    public get(reducerKey: string) {
        return lodash.cloneDeep(lodash.get(this.state, reducerKey));
    }
    public set(reducerKey: string, data: any, action: any) {
        const reducer = this.reduers[reducerKey];
        if(reducer) {
            const oldState = lodash.get(this.state, reducerKey);
            const updateData = reducer.handler(oldState, {
                state: this.state,
                action: {
                    type: "@Store_Update",
                    name: reducerKey,
                    ...(action || {}),
                    data
                }
            });
            const eventHandler = this.listener[reducerKey];
            lodash.set(this.state, reducerKey, updateData);
            if(eventHandler) {
                eventHandler.forEach((item) => {
                    item.callback(updateData, this.state);
                });
            }

        } else {
            console.error(`更新失败，错误的节点: ${reducerKey}`);
        }
    }
    public on(reducerKey: string, callback: Function) {
        const eventId: string = lodash.uniqueId("state_event");
        if(!this.listener[reducerKey]) {
            this.listener[reducerKey] = [];
        }
        this.listener[reducerKey].push({
            id: eventId,
            callback
        });
        return () => {
            const index = this.listener[reducerKey].findIndex((item: any) => item.id === eventId);
            if(index > -1) {
                this.listener[reducerKey].splice(index, 1);
            }
        }
    }
}